package com.zone.gateway.core.session;

import com.zone.gateway.core.authorization.IAuthService;
import com.zone.gateway.core.authorization.auth.AuthService;
import com.zone.gateway.core.bind.IGenericReference;
import com.zone.gateway.core.bind.MappedRegister;
import com.zone.gateway.core.datasource.Connection;
import com.zone.gateway.core.executor.Executor;
import com.zone.gateway.core.executor.SimpleExecutor;
import com.zone.gateway.core.mapping.HttpStatement;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.rpc.service.GenericService;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author: zongzi
 * @description: 会话上下文
 * @date: 2025/4/17
 */
public class Configuration {
    // 服务名 - 应用配置
    private final Map<String, ApplicationConfig> applicationConfigMap = new HashMap<>();
    // 服务名 - 注册中心配置
    private final Map<String, RegistryConfig> registryConfigMap = new HashMap<>();
    // 接口全限定路径 - 泛化服务
    private final Map<String, ReferenceConfig<GenericService>> referenceConfigMap = new HashMap<>();

    // uri - http信息缓存
    private final Map<String, HttpStatement> httpStatementMap = new ConcurrentHashMap<>();

    // 泛化服务注册器
    private final MappedRegister register = new MappedRegister(this);

    // netty server 配置信息
    private int nettyServerPort = 7397;
    private int bossNThreads = 1;
    private int workerNThreads = 4;

    public Configuration() {

    }

    public synchronized void regisConfig(String applicationName, String registerAddress, String interfaceName, String interfaceVersion) {
        ApplicationConfig config = applicationConfigMap.computeIfAbsent(applicationName, key -> {
            ApplicationConfig applicationConfig = new ApplicationConfig();
            applicationConfig.setName(key);
            return applicationConfig;
        });

        RegistryConfig registryConfig = new RegistryConfig();
        registryConfig.setAddress(registerAddress);
        registryConfig.setTimeout(100000);  // 设置超时时间
        registryConfigMap.put(applicationName, registryConfig);

        ReferenceConfig<GenericService> referenceConfig = new ReferenceConfig<>();
        referenceConfig.setInterface(interfaceName);
        referenceConfig.setVersion(interfaceVersion);
        referenceConfig.setRegistry(registryConfig);
        referenceConfig.setApplication(config);
        referenceConfig.setGeneric("true");
        referenceConfig.setTimeout(7000);
        referenceConfigMap.put(interfaceName, referenceConfig);
    }

    public ReferenceConfig<GenericService> getReferenceConfig(String interfaceName) {
        return referenceConfigMap.get(interfaceName);
    }

    public IGenericReference getMapped(String uri, GatewaySession gatewaySession) {
        return register.getMapped(uri, gatewaySession);
    }

    public void addMapped(HttpStatement httpStatement) {
        // 注册代理工厂到注册器
        register.regis(httpStatement);
        // 注册uri-http语句
        this.addHttpStatement(httpStatement);
    }

    public HttpStatement getHttpStatement(String uri) {
        return httpStatementMap.get(uri);
    }

    public void addHttpStatement(HttpStatement httpStatement) {
        httpStatementMap.put(httpStatement.getUri(), httpStatement);
    }


    public Executor getExecutor(Connection connection) {
        return new SimpleExecutor(this, connection);
    }

    public boolean auth(String uId, String token) {
        IAuthService authService = new AuthService();
        return authService.validate(uId, token);
    }

    public int getNettyServerPort() {
        return nettyServerPort;
    }

    public void setNettyServerPort(int nettyServerPort) {
        this.nettyServerPort = nettyServerPort;
    }

    public int getBossNThreads() {
        return bossNThreads;
    }

    public void setBossNThreads(int bossNThreads) {
        this.bossNThreads = bossNThreads;
    }

    public int getWorkerNThreads() {
        return workerNThreads;
    }

    public void setWorkerNThreads(int workerNThreads) {
        this.workerNThreads = workerNThreads;
    }
}
